package cmd

import (
	"fmt"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"metabank/cache"
	"metabank/conf"
	"metabank/constants"
	"metabank/informers"
	"net/http"
	"path"
)

type ServerOptions struct {
	// server bind address
	BindAddress string

	// insecure port number
	InsecurePort int

	// secure port number
	SecurePort int

	// tls cert file
	TlsCertFile string

	// tls private key file
	TlsPrivateKey string
}

type ServerRunOptions struct {
	GenericServerRunOptions *ServerOptions
	*conf.Config
}

func NewServerOptions() *ServerOptions {
	// create default server run options
	so := ServerOptions{
		BindAddress:   "0.0.0.0",
		InsecurePort:  9090,
		SecurePort:    0,
		TlsCertFile:   "",
		TlsPrivateKey: "",
	}

	return &so
}

func NewServerRunOptions() *ServerRunOptions {
	sro := &ServerRunOptions{
		GenericServerRunOptions: NewServerOptions(),
		Config:                  conf.New(),
	}

	return sro
}

func (s *ServerRunOptions) NewAPIServer() (*APIServer, error) {

	apiServer := &APIServer{
		Config: s.Config,
		Caches: make(map[string]map[string]string),
	}

	// 本地kubeconfig文件调用k8s接口
	//k8sConfigPath := path.Join(constants.ConfigPath, constants.K8sConfigName)
	//k8sConfig, err := clientcmd.BuildConfigFromFlags("", k8sConfigPath)
	//if err != nil {
	//	return nil, err
	//}

	//SA 调用k8s接口
	k8sConfig, err := rest.InClusterConfig()
	if err != nil {
		return nil, err
	}

	mcpConfigPath := path.Join(constants.ConfigPath, constants.McpConfigName)
	mcpConfig, err := clientcmd.BuildConfigFromFlags("", mcpConfigPath)
	if err != nil {
		return nil, err
	}

	mcpClient, err := kubernetes.NewForConfig(mcpConfig)
	if err != nil {
		return nil, err
	}
	k8sClient, err := kubernetes.NewForConfig(k8sConfig)
	if err != nil {
		return nil, err
	}

	apiServer.K8sClient = k8sClient
	apiServer.McpClient = mcpClient
	informerFactory := informers.NewInformerFactories(k8sClient)
	apiServer.InformerFactory = informerFactory

	apiServer.SyncInformer = cache.SyncInformers(informerFactory.KubernetesSharedInformerFactory(), mcpClient, s.Config, apiServer.Caches)

	server := &http.Server{
		Addr: fmt.Sprintf(":%d", s.GenericServerRunOptions.InsecurePort),
	}

	apiServer.Server = server
	return apiServer, nil
}
